#include"udp_server.hpp"
#include <iostream>
#include <fstream>
#include <utility>
#include <signal.h>


#include<map>

using namespace zxf;
void usage()
{
    std::cout<<"\n usage:\n     ./udp_server bind_port"<<std::endl;

}

// //字典处理
// static std::string dictpath = "./dict.txt";
// static std::map<std::string , std::string> dictmap;
// //字典读取配置文件
// void initdict()
// {
//     std::ifstream ifs(dictpath, std::ios_base::in);
//     std::string line;
//     while(getline(ifs, line))//这里getline返回的是 fstream 这个类重载了 operator bool()
//     {//行拿取出
        
//         std::string tmp = ":";
//         size_t i = line.find(tmp);
//         if(i == std::string::npos)
//         {
//             std::cout<<"配置文件格式不对"<<std::endl;
//             exit(INITDICT_ERR);
//         }
//         std::string key = line.substr(0,i);
//         std::string val = line.substr(i+tmp.size());
//         dictmap.insert(make_pair(key, val));
//     }
//     std::cout<<"initdict success"<< std::endl;
// }


// //热加载含糊
// void handler (int sig)
// {
//     initdict();
// }

// //字典deno
// void callback(int& _serverfd, struct sockaddr_in& c_addr , std::string message)
// {

//     auto it = dictmap.find(message);
//     if(it == dictmap.end()){
//         message = "Unknown error";
//     }
//     else{
//         message = it->second;
//     }
//     //处理完毕 //info 发回去

//     sendto(_serverfd,message.c_str(), message.size(), 0 , (struct sockaddr*)&c_addr, sizeof(c_addr));
// }


// //shell模仿
// void shell(int& _serverfd, struct sockaddr_in& c_addr , std::string message)
// {
//     FILE *fp = popen(message.c_str(), "r");
//     if(fp == nullptr) 
//     {
//         message += "\n error \n";
//     }
//     char line[1024];
//     message.clear();
//     while(fgets(line, sizeof(line), fp))
//     {
//         message += line;
//     }
//     pclose(fp);

//     //返回
//     sendto(_serverfd,message.c_str(), message.size(), 0 , (struct sockaddr*)&c_addr, sizeof(c_addr));
// }


#include"users.hpp"
users us;
//多人聊天室
void chat(int& _serverfd, struct sockaddr_in& c_addr , std::string message)
{
    std::string ip = inet_ntoa(c_addr.sin_addr);
    uint16_t port = ntohs(c_addr.sin_port);

    if(strcmp(message.c_str(), "online") == 0 )
    {
        us.insert(ip,port);
       
        message += " success!!";
        //返回
        sendto(_serverfd,message.c_str(), message.size(), 0 , (struct sockaddr*)&c_addr, sizeof(c_addr));
    }
    else if(strcmp(message.c_str(), "offline") == 0)
    {
        //退出
        us.del(ip,port);
        message += " success!!";
        //返回
        sendto(_serverfd,message.c_str(), message.size(), 0 , (struct sockaddr*)&c_addr, sizeof(c_addr));
    }
    else{
        //查找在线表格,看此人是否在线
        if(us.isonline(ip,port))
        {
            std::string ref="";
            ref += "["+ip  + std::to_string(port)+"]: ";
            ref += message;
            //群发info
            us.groupinfo(_serverfd, ref);
        }
        else{
            //单独发送"请先上线"
            message.clear();
            message = "你还未上线 请先输入 online";
            //返回
            sendto(_serverfd,message.c_str(), message.size(), 0 , (struct sockaddr*)&c_addr, sizeof(c_addr));
        }
    }

}







int main(int argc, char* argv[])
{
    if(argc != 2)
    {
        usage();
        exit(USAGE_ERR);
    }
    uint16_t port = std::stoi(argv[1]);//获取端口号

    //加载字典
    //initdict();
    //signal(2, handler);

    



    server* so = new server(port);//创建服务器对象
    so->initserer();//初始化服务器

    //so->runserver(callback);//启动服务器
    //so->runserver(shell);//启动服务器
    so->runserver(chat);//启动服务器


    std::cout<<"server:测试";
}